package tgc.edu.exam.web.controller;

import java.util.HashSet;
import java.util.List;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import tgc.edu.exam.custom.CommonController;
import tgc.edu.exam.entity.AssessmentInformation;
import tgc.edu.exam.entity.Student;
import tgc.edu.exam.entity.StudentAssess;
import tgc.edu.exam.entity.StudentInformation;
import tgc.edu.exam.entity.SysRole;
import tgc.edu.exam.entity.SysUser;
import tgc.edu.exam.entity.TbClass;
import tgc.edu.exam.entity.Teacher;
import tgc.edu.exam.security.UserUtils;
import tgc.edu.exam.service.AssessmentInformationService;
import tgc.edu.exam.service.StudentAssessService;
import tgc.edu.exam.service.StudentInformationService;
import tgc.edu.exam.service.StudentService;
import tgc.edu.exam.service.TbClassService;
import tgc.edu.exam.web.form.StudentAssessForm;

@Controller
@RequestMapping(value = "/studentAssess")
public class StudentAssessController extends CommonController<StudentAssess, UUID, StudentAssessForm> {
	@Autowired
	private StudentAssessService service;
	@Autowired
	private TbClassService tbClassService;
	@Autowired
	private StudentService stuService;
	@Autowired
	private UserUtils userUtils;
	@Autowired
	private AssessmentInformationService informateionService;
	@Autowired
	private StudentInformationService stuInformationService;

	@RequestMapping(value = "/details")
	public void details(String id, String bjid, ModelMap map) {
		Specification<StudentInformation> spec = buildSpec2(id, null);
		List<StudentInformation> list = stuInformationService.findAll(spec);
		List<AssessmentInformation> list1 = informateionService.findByTbClassid(bjid);
		if (list.size() != list1.size()) {
			for (AssessmentInformation assessmentInformation : list1) {
				Specification<StudentInformation> spec2 = buildSpec2(id, assessmentInformation.getId().toString());
				List<StudentInformation> list2 = stuInformationService.findAll(spec2);
				if (list2.size() == 0) {
					StudentInformation stuInformation = new StudentInformation();
					stuInformation.setInformation(assessmentInformation);
					stuInformation.setAssess(service.findById(UUID.fromString(id)));
					stuInformationService.save(stuInformation);
				}
			}
		}
		list.clear();
		list = stuInformationService.findAll(spec);
		map.put("data", list);
	}

	@RequestMapping(value = "/tijiao")
	@ResponseBody
	public Object tijiao(String id, String grades) {
		UUID ids = UUID.fromString(id);
		double actualscore = 0;
		String msg = "无消息";
		try {
			double grade = Double.parseDouble(grades);
			StudentInformation studentInformation = stuInformationService.findById(ids);
			if (studentInformation.getInformation().getScore() >= grade) {
				studentInformation.setGrade(grade);
				stuInformationService.save(studentInformation);
				Specification<StudentInformation> spec = buildSpec2(studentInformation.getAssess().getId().toString(),
						null);
				List<StudentInformation> list = stuInformationService.findAll(spec);
				for (StudentInformation studentInformation2 : list) {
					actualscore += studentInformation2.getGrade();
				}
				StudentAssess studentAssess = service.findById(studentInformation.getAssess().getId());
				studentAssess.setActualscore(actualscore);
				service.save(studentAssess);
			} else {
				msg = studentInformation.getInformation().getExamination() + "最高分值为"
						+ studentInformation.getInformation().getScore() + "！请勿错误填写";
			}
		} catch (Exception e) {
			msg = "得分请填写正确格式！";
		}
		return msg;
	}

	@Override
	public void manage(ModelMap map) {
		boolean ishas = false;
		SysUser sysUser = userUtils.getUser();
		if (sysUser != null) {
			List<SysRole> roles = sysUser.getRoles();
			for (SysRole sysRole : roles) {
				List<SysRole> children = sysRole.getChildren();
				for (SysRole sysRole2 : children) {
					String code = "ROLE_GWCJCX";
					String rolecode = sysRole2.getCode();
					if (code.equals(rolecode)) {
						ishas = true;
					}
				}
			}
			Specification<TbClass> spec = buildSpec5(null);
			List<TbClass> tbClass = tbClassService.findAll(spec);
			for (TbClass tbClass2 : tbClass) {
				double score = 0;
				List<AssessmentInformation> list1 = informateionService.findByTbClassid(tbClass2.getId().toString());
				for (AssessmentInformation assessmentInformation : list1) {
					score += assessmentInformation.getScore();
				}
				Specification<StudentAssess> spec1 = buildSpec3(tbClass2);
				Specification<Student> spec2 = buildSpec4(tbClass2);
				List<Student> students = stuService.findAll(spec2);
				List<StudentAssess> list = service.findAll(spec1);
	    		if (students.size() != list.size()) {
	    			for (Student student : students) {
	    				StudentAssess stuAssess = service.findByStudent(student);
	    				if (stuAssess == null) {
	    					StudentAssess assess = new StudentAssess();
	    					assess.setStudent(student);
	    					assess.setScore(score);
	    					assess.setBanjiid(student.getTbClass().getId().toString());
	    					assess.setBanji(student.getTbClass().getName());
	    					service.save(assess);
	    				}
	    			}
	    		}
				StudentAssessForm form = new StudentAssessForm();
				form.setBjuuid(tbClass2.getId().toString());
				Specification<StudentAssess> spec3 = buildSpec(form);
				List<StudentAssess> list3 = service.findAll(spec3);
				for (StudentAssess stuassess : list3) {
					if (stuassess.getScore() != score) {
						stuassess.setScore(score);
						service.save(stuassess);
					}
				}
			}

			if (ishas) {
				map.put("data", tbClass);
			} else {
				Specification<TbClass> spec1 = buildSpec5(sysUser);
				List<TbClass> list = tbClassService.findAll(spec1);
				map.put("data", list);
			}
		} else {
			ishas = true;
			Specification<TbClass> spec = buildSpec5(null);
			List<TbClass> list = tbClassService.findAll(spec);
			map.put("data", list);
		}
		map.put("ishas", ishas);
		super.manage(map);
	}

	@RequestMapping(value = "/banjiselect")
	@ResponseBody
	public Object banjiselect(boolean isstart) {
		if (isstart) {
			List<TbClass> bjs = tbClassService.findAll();
			for (TbClass tbClass : bjs) {
				String state = tbClass.getClassStatus().getState();
				if ("结业".equals(state)) {
					tbClass.setName(tbClass.getName() + "(结业班级)");
				}
			}
			return bjs;
		} else {
			Specification<TbClass> spec = buildSpec5(null);
			List<TbClass> bjs = tbClassService.findAll(spec);
			return bjs;
		}
	}

	private Specification<TbClass> buildSpec5(SysUser sysUser) {
		Specification<TbClass> spec = new Specification<TbClass>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<TbClass> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if (sysUser != null) {
					rules.add(cb.equal(root.get("teacherId").get("id"), sysUser.getId()));
				}
				rules.add(cb.equal(root.get("classStatus").get("state"), "开班"));
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

	private Specification<Student> buildSpec4(TbClass tbClass2) {
		Specification<Student> spec = new Specification<Student>() {

			@Override
			public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();

				rules.add(cb.equal(root.get("tbClass").get("id"), tbClass2.getId()));
				rules.add(cb.notEqual(root.get("tbClass").get("classStatus").get("state"), "结业"));
				rules.add(cb.equal(root.get("isUsed"), true));

				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

	private Specification<StudentInformation> buildSpec1(StudentAssess stuAssess,
			AssessmentInformation assessmentInformation) {
		Specification<StudentInformation> spec = new Specification<StudentInformation>() {

			@Override
			public Predicate toPredicate(Root<StudentInformation> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				rules.add(cb.equal(root.get("assess"), stuAssess));
				rules.add(cb.equal(root.get("information"), assessmentInformation));
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

	private Specification<StudentInformation> buildSpec2(String id, String informationid) {
		Specification<StudentInformation> spec = new Specification<StudentInformation>() {

			@Override
			public Predicate toPredicate(Root<StudentInformation> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if (StringUtils.hasText(id)) {
					rules.add(cb.equal(root.get("assess").get("id"), UUID.fromString(id)));
				}
				if (StringUtils.hasText(informationid)) {
					rules.add(cb.equal(root.get("information").get("id"), UUID.fromString(informationid)));
				}
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

	private Specification<StudentAssess> buildSpec3(TbClass tbClass2) {
		Specification<StudentAssess> spec = new Specification<StudentAssess>() {

			@Override
			public Predicate toPredicate(Root<StudentAssess> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				rules.add(cb.equal(root.get("student").get("tbClass"), tbClass2));
				return cb.or(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

	@Override
	public Specification<StudentAssess> buildSpec(StudentAssessForm form) {
		Specification<StudentAssess> spec = new Specification<StudentAssess>() {

			@Override
			public Predicate toPredicate(Root<StudentAssess> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				String username = form.getUsernam();
				if (StringUtils.hasText(username)) {
					rules.add(cb.like(root.get("student").get("username"), "%" + username + "%"));
				}
				String name = form.getName();
				if (StringUtils.hasText(name)) {
					rules.add(cb.like(root.get("student").get("name"), "%" + name + "%"));
				}
				String bjuuid = form.getBjuuid();
				if (StringUtils.hasText(bjuuid)) {
					rules.add(cb.equal(root.get("banjiid"), bjuuid));
				}
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

}
